/*
 * Copyright (C) 2014 Lucid Wolf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.lucidhex.io;

import com.lucidhex.LucidWorld;
import com.lucidhex.LucidXMLObject;
import com.lucidhex.viewer.LucidIcon;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Not only does this do the file manipulations it does the 
 * Converter uses Reflections library to find all classes that implement the LucidXMLParser
 * interface.  This may seem redundant but helped simplify writing a bunch Converters
 * Probably bastardizing what they wanted... Wont be the first or the last.
 * Do like that using xstream for some data types is just a few annotations and im good
 * @author Wolf
 */
public class LucidWorldParser{
    XStream xStream = new XStream(new StaxDriver());
    ArrayList<LucidXMLObjectConverter> parsers = new ArrayList<>();
    LucidWorld world = null;
    public LucidWorldParser(){
        registerXStreamParamaters();
        System.out.println();
    }
    private void registerXStreamParamaters() {
        // scan jar/class files for lucidhex package and LucidXMLObjects
        // register the LucidXMLObject and created Converter
        Reflection reflections = new Reflection("com.lucidhex");
        Set<Class> subTypes = reflections.getSubTypesOf(LucidXMLObject.class);    
        for(Class<? extends LucidXMLObject> c : subTypes){
            try {
                LucidXMLObject o = c.newInstance(); //test it before its an Xstream issue
                LucidXMLObjectConverter lop = new LucidXMLObjectConverter(this, c);
                parsers.add(lop);
                xStream.alias(o.getTag(), c);
                xStream.registerConverter(lop);                
            } catch (    InstantiationException | IllegalAccessException ex){
                Logger.getLogger(LucidWorldParser.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        // now register custom Alias and Converters
        // svg tags are svg graphics which are turned into LucidIcons
        LucidIconConverter svgic = new LucidIconConverter();
        xStream.alias("Icon_SVG", LucidIcon.class);
        xStream.registerConverter(svgic);
        
    }
    public LucidWorld parseFromFile(File aFile){
        // o is not needed because we link the world and first parse
        world = null;
        Object o = xStream.fromXML(aFile);
        return world;
    }    

    public void parseToFile(File file, LucidWorld world){
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(file);
            pw.println(xStream.toXML(world));
            pw.flush();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(LucidWorldParser.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            pw.close();
        }
    }

    public LucidWorld getParsingWorld() {
        return world;
    }
    public void setParsingWorld(LucidWorld world) {
        this.world = world;
    }
    
    public XStream getXstream() {
        return xStream;
    }



}
